import { useRef, useState, useMemo, type FC } from "react";
import { Space, Button, Avatar, message } from "antd";
import useUserStore, { selectAvatar } from "@/store/user-store";
import { type ActionFunctionArgs, useSubmit } from "react-router-dom";
import { updateAvatarApi } from "@/api/user-api";
import to from "await-to-js";
import { useNavSubmitting } from "@/utils/hooks";

const UserAvatar: FC = () => {
  const submit = useSubmit();
  const fileRef = useRef<HTMLInputElement>(null);
  const avatar = useUserStore(selectAvatar);
  const [newAvatar, setNewAvatar] = useState("");
  const submitting = useNavSubmitting("PATCH");

  // 动态计算，并缓存计算的结果
  const isDisabled = useMemo(() => !newAvatar || newAvatar === avatar, [newAvatar, avatar]);

  const onFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    // 获取文件列表
    const files = e.currentTarget.files;
    // 判断文件列表是否有值
    if (!files || files.length === 0) return;

    // 创建文件读取器
    const fr = new FileReader();
    // 以 base64 的形式读取文件
    fr.readAsDataURL(files[0]);
    fr.onload = () => {
      if (fr.result) {
        setNewAvatar(fr.result as string);
      }
    };
  };

  const saveAvatar = () => {
    if (submitting) return;
    submit({ avatar: newAvatar }, { method: "PATCH" });
  };
  return (
    <Space direction="vertical">
      {/* 按需渲染头像组件 */}
      {newAvatar || avatar ? (
        <Avatar size={300} shape="square" src={newAvatar || avatar} />
      ) : (
        <Avatar size={300} shape="square">
          请选择头像
        </Avatar>
      )}

      <Space direction="horizontal">
        <input ref={fileRef} style={{ display: "none" }} type="file" accept="image/*" onChange={onFileChange} />
        <Button onClick={() => fileRef.current?.click()}>选择照片</Button>
        <Button type="primary" disabled={isDisabled} onClick={saveAvatar} loading={submitting && { delay: 200 }}>
          保存头像
        </Button>
      </Space>
    </Space>
  );
};

export default UserAvatar;

export const action = async ({ request }: ActionFunctionArgs) => {
  const fd = await request.formData();
  const [err] = await to(updateAvatarApi(fd));
  if (err) return null;
  message.success("头像更新成功");
  return null;
};
